<?php
/**
 * Created by PhpStorm.
 * User: 12297
 * Date: 2018/5/15
 * Time: 0:03
 */
namespace app\admin\service;

use app\common\BaseHelper;
use app\common\DictConstant;
use app\common\model\Order;
use app\common\model\Ordercommission;
use app\common\model\Orderproductdetail;
use app\common\model\Refundorder;
use app\common\model\User;
use app\common\model\Useraccountdetails;
use app\lib\exception\ParameterException;
use think\Db;
use think\Exception;
use think\Loader;

Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');

/**
 * 订单售后处理
 * Class Refund
 * @package app\admin\service
 */
class Refund{
    private $orderNO;
    private $productId;
    private $actiontype;
    private $post_refund_fee = 0;
    private $fefund_isall;
    private $content = null;

    function __construct($postdata)
    {
        $this->orderNO = $postdata['orderNO'];
        $this->productId = $postdata['productId'];
        $this->actiontype = $postdata['actiontype'];
        $this->fefund_isall = $postdata['fefund_isall'];
        if($this->fefund_isall == 0){
            $this->post_refund_fee = $postdata['refund_fee'];
        }
        $this->content = isset($postdata['content'])?$postdata['content']:null;
    }

    public function actionrefund(){
        $refundorder = Refundorder::where(['orderNO'=>$this->orderNO,'productId'=>$this->productId])->find();
        if(!$refundorder){
            throw new ParameterException([
                'msg' => '该售后订单不存在'
            ]);
        }


        //拒绝售后
        if($this->actiontype==0){
            //拒绝售后
            try{
                $this->checkrefundorder($refundorder);
                $refuseReason = $this->content;
                $refundorder->content = $refuseReason;
                $refundorder->status = 1;
                $refundorder->save();
                $order = Order::where('orderNO','=',$this->orderNO)->find();
                $order->status = DictConstant::Order_Refuse;
                $order->save();

                return show(config('status.SUCCESS_STATUS'),'已经拒绝售后',$refuseReason);
            }catch (Exception $ex){
                return show(config('status.ERROR_STATUS'),$ex->msg,$ex->msg);
            }

        }


        //判断该订单状态
        //1.历史状态为2未发货，直接退款，或者不同意退款
        //2.历史状态为3已发货，则需要先同意售后，然后再由用户进行退货相关处理。或者不同意售后
        //3.历史状态为8未消费订单，直接退款，或者不同意退款
        $orderhistory = Orderproductdetail::get($refundorder->orderProductDetailId);
        $order = Order::where('orderNO',$this->orderNO)->find();
        $payMethod = $order->payMethod;
        return $this->ActiveRefund($orderhistory->oldStatus,$refundorder->out_refund_no,$payMethod);
    }

    //同意售后
    private function ActiveRefund($oldStatus,$out_refund_no,$payMethod){
        if($oldStatus==2 || $oldStatus==8){
            //订单未发货或者未消费,同意并退款
            if($payMethod == 0){
                //微信支付
                return $this->Refund($out_refund_no);
            }else{
                //账户余额支付
                $res = $this->balanceRefund($out_refund_no);
                if($res['status'] == 1){
                    return show(config('status.SUCCESS_STATUS'),'退还余额成功','退还余额成功');
                }else{
                    return show(config('status.ERROR_STATUS'),'退还余额失败','退还余额失败');
                }
            }


        }elseif ($oldStatus==4 || $oldStatus==3){
            //订单已经发货或者确认收货，用户联系商家自行处理

        }
    }

    private function balanceRefund($out_refund_no){
        Db::startTrans();
        try{
            $refundorder = Refundorder::where(['out_refund_no'=>$out_refund_no])->find();
            $this->checkrefundorder($refundorder);
            if($this->fefund_isall == 0){
                if($this->post_refund_fee > $refundorder->refund_fee){
                    return show(config('status.ERROR_STATUS'),'退款金额不能大于订单金额','退还余额失败');
                }
                $refund_fee = $this->post_refund_fee * 100;
            }else{
                $refund_fee = $refundorder->refund_fee;
            }
            $endDate = date('Y-m-d H:i:s',time());
            $refundorder->endDate = $endDate;
            $refundorder->refund_channel = 1;
            $refundorder->actualrefund_fee = $refund_fee;
            $refundorder->status = 2;
            $refundorder->save();
            $order = Order::where('orderNO','=',$this->orderNO)->find();
            $order->status = DictConstant::Order_Agree;
            $order->save();
            //退余额
            User::where('id',$refundorder->userId)->setInc('balance',$refund_fee);
            //用户账户充值与消费明细表中插入记录
            $Useraccountdetails = new Useraccountdetails();
            $Useraccountdetails->insertRecord($refundorder,Useraccountdetails::TYPE_2,Useraccountdetails::MODEL_2);
            if($order->saleRuleId){
                //如果这笔订单产生了佣金，则要减去相应的佣金
                $this->minusCommission($refundorder->refund_fee,$order->id,$order->createUser);
            }
            Db::commit();
            return [
                'status' => 1,
                'message' => '退还余额成功'
            ];
        }catch (Exception $ex){
            Db::rollback();
            return [
                'status' => 0,
                'message' => '退款失败'
            ];

        }
    }



    private function Refund($out_refund_no){
        $refundorder = Refundorder::where(['out_refund_no'=>$out_refund_no])->find();
        try{
            $this->checkrefundorder($refundorder);
            if($this->fefund_isall == 0){
                if($this->post_refund_fee > $refundorder->refund_fee){
                    throw new ParameterException([
                        'msg' => '退款金额不能大于订单总额'
                    ]);
                }
                $refund_fee = $this->post_refund_fee;
            }else{
                $refund_fee = $refundorder->refund_fee;
            }
        }catch (Exception $ex){
            return show(config('status.ERROR_STATUS'),$ex->msg,$ex->msg);
        }

        $wxRefundData = new \WxPayRefund();

        $wxRefundData->SetTotal_fee($refundorder->oldTotal);
        $wxRefundData->SetOut_trade_no($refundorder->orderNO);
        $wxRefundData->SetOut_refund_no($out_refund_no);
        $wxRefundData->SetRefund_fee($refund_fee);

        return $this->WxRefund($wxRefundData,$refundorder->tenantId);

    }

    private function WxRefund($wxRefundData,$tenantId){
        $wxRefund = \WxPayApi::grouprefund($wxRefundData,$tenantId);
        if($wxRefund['return_code'] != 'SUCCESS' || $wxRefund['result_code'] != 'SUCCESS'){
            $wxRefund['status'] = 0;
            $wxRefund['message'] = '退款失败';
        }else{
            //微信退款成功后的处理逻辑
            $wxRefund['status'] = 1;
            $wxRefund['message'] = '退款成功';
            $this->WxRefundSuccess($wxRefund);

        }
        return $wxRefund;
    }

    private function WxRefundSuccess($wxRefund){
//        <xml>
//       <return_code><![CDATA[SUCCESS]]></return_code>
//       <return_msg><![CDATA[OK]]></return_msg>
//       <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
//       <mch_id><![CDATA[10000100]]></mch_id>
//       <nonce_str><![CDATA[NfsMFbUFpdbEhPXP]]></nonce_str>
//       <sign><![CDATA[B7274EB9F8925EB93100DD2085FA56C0]]></sign>
//       <result_code><![CDATA[SUCCESS]]></result_code>
//       <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>
//       <out_trade_no><![CDATA[1415757673]]></out_trade_no>
//       <out_refund_no><![CDATA[1415701182]]></out_refund_no>
//       <refund_id><![CDATA[2008450740201411110000174436]]></refund_id>
//       <refund_channel><![CDATA[]]></refund_channel>
//       <refund_fee>1</refund_fee>
//        </xml>
        Db::startTrans();
        try{
            $mch_id = $wxRefund['mch_id'];
            $refund_id = $wxRefund['refund_id'];
            $endDate = date('Y-m-d H:i:s',time());
            $refundorder = Refundorder::where('out_refund_no','=',$wxRefund['out_refund_no'])->find();
            $refundorder->refund_id = $refund_id;
            $refundorder->op_user_id = $mch_id;
            $refundorder->endDate = $endDate;
            $refundorder->refund_channel = 0;
            $refundorder->actualrefund_fee = $wxRefund['refund_fee'];
            $refundorder->status = 2;
            $refundorder->save();
            $order = Order::where('orderNO','=',$wxRefund['out_trade_no'])->find();
            $order->status = DictConstant::Order_Agree;
            $order->save();
            if($order->saleRuleId){
                //如果这笔订单产生了佣金，则要减去相应的佣金
               $this->minusCommission($wxRefund['refund_fee'],$order->id,$order->createUser);
            }
            $Useraccountdetails = new Useraccountdetails();
            $Useraccountdetails->insertRecord($refundorder,Useraccountdetails::TYPE_7,Useraccountdetails::MODEL_2);
            Db::commit();
        }catch (Exception $ex){
            Db::rollback();
            Log::record($ex);
        }




    }

    private function minusCommission($refund_fee,$orderId,$userId){
        Ordercommission::where(['orderId'=>$orderId,'userId'=>$userId,'status'=>0])->setDec('total',$refund_fee);
    }


    private function checkrefundorder($refundorder){
        if($refundorder->status != 4){
            throw new ParameterException([
                'msg' => '该订单不能售后了'
            ]);
        }
        if(!$refundorder){
            throw new ParameterException([
                'msg' => '该售后订单不存在'
            ]);
        }
    }

    /**
     * @return string
     */
   public function getRandom(){
        $str="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $key = "";
        $key .= $str{mt_rand(0,32)};    //生成php随机数
        return $key;
    }

}